package thread;

/**
 * 避免死锁:
 * 1:尽可能避免一个线程在持有一个锁的同时去持有另一个锁
 *   避免synchronized套synchronized的情况
 * 2:若无法避免第一条，则必须保证持有锁的顺序多个线程要一致！
 *   以下面的代码为例，就必须保证若先持有chopstick里面再持有spoon时，所有线程都要以该顺序持有锁
 */
public class DeadLockDemo2 {
    public static Object chopstick = new Object();//筷子
    public static Object spoon = new Object();//勺

    public static void main(String[] args) {
        //北方人
        Thread np = new Thread(){
            public void run(){
                try {
                    System.out.println("北方人开始吃饭");
                    System.out.println("北方人去拿筷子...");
                    synchronized (chopstick) {
                        System.out.println("北方人拿起了筷子，开始吃饭...");
                        Thread.sleep(5000);//吃饭过程...
                    }
                    System.out.println("北方人吃完了饭并放下了筷子");
                    System.out.println("北方人去拿勺...");
                    synchronized (spoon){
                        System.out.println("北方人拿起了勺，开始喝汤...");
                        Thread.sleep(5000);//喝汤过程...
                    }
                    System.out.println("北方人喝完了汤并放下了勺");
                } catch (InterruptedException e) {
                }
            }
        };

        //南方人
        Thread sp = new Thread(){
            public void run(){
                try {
                    System.out.println("南方人开始吃饭");
                    System.out.println("南方人去拿勺...");
                    synchronized (spoon) {
                        System.out.println("南方人拿起了勺，开始喝汤...");
                        Thread.sleep(5000);//喝汤过程...
                    }
                    System.out.println("南方人喝完了汤并放下了勺");
                    System.out.println("南方人去拿筷子...");
                    synchronized (chopstick){
                        System.out.println("南方人拿起了筷子，开始吃饭...");
                        Thread.sleep(5000);//吃饭过程...
                    }
                    System.out.println("南方人吃完了饭并放下了筷子");
                } catch (InterruptedException e) {
                }
            }
        };
        sp.start();
        np.start();
    }
}
